package com.xianniu.ltc.aspect;

import cn.devezhao.persist4j.Entity;
import cn.devezhao.persist4j.Record;
import cn.devezhao.persist4j.engine.ID;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rebuild.core.Application;
import com.rebuild.core.UserContextHolder;
import com.rebuild.core.configuration.ConfigBean;
import com.rebuild.core.configuration.general.FormsBuilder;
import com.rebuild.core.configuration.general.FormsManager;
import com.rebuild.core.metadata.EntityHelper;
import com.rebuild.core.metadata.MetadataHelper;
import com.rebuild.core.privileges.UserHelper;
import com.rebuild.core.privileges.UserService;
import com.rebuild.core.service.notification.Message;
import com.rebuild.core.service.notification.MessageBuilder;
import com.rebuild.core.support.i18n.Language;
import com.rebuild.web.InvalidParameterException;
import com.xianniu.ltc.mapper.TCaigouguanliMapper;
import com.xianniu.ltc.mapper.TRbhetong0Mapper;
import com.xianniu.ltc.mapper.TRbshangji1Mapper;
import com.xianniu.ltc.model.entity.*;
import com.xianniu.ltc.model.po.ProjectAddPO;
import com.xianniu.ltc.model.po.ProjectAndDetailUpdatePO;
import com.xianniu.ltc.model.po.ProjectUpdatePO;
import com.xianniu.ltc.model.po.ProjectUserPO;
import com.xianniu.ltc.service.ProjectService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author dingyuxin
 *  todo 后续优化成异步
 */
@Slf4j
@Aspect
@Component
public class RecordSaveAspect {
    @Value("${H5-URL}")
    private String h5Url;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private TRbhetong0Mapper tRbhetong0Mapper;
    @Autowired
    private  TCaigouguanliMapper caigouguanliMapper;
    @Resource
    private TRbshangji1Mapper rbshangji1Mapper;

    /**
     * 只有发送消息的时候触发
     * com.rebuild.core.service.notification
     */
    @Pointcut("execution(public * com.rebuild.web.general.GeneralOperatingController.*(..))")
    public void sendMessage(){}

    /**
     * 前置通知：在连接点之前执行的通知
     * @param joinPoint
     * @throws Throwable
     */
    @Around("sendMessage()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        final String saveMark = "save";
        final String deleteMark = "delete";
        // 分派：通过数据ID查询项目明细表是否存在，得到项目ID，然后查询项目用户关系表是否存在，不存在则新增项目-人员关系表
        final String assignMark = "assign";
        // 共享：通过数据ID查询项目明细表是否存在，得到项目ID，然后查询项目用户关系表是否存在，不存在则新增项目-人员关系表
        final String shareMark = "share";
        // 取消共享：通过数据ID查询项目明细表是否存在，得到项目ID，然后查询项目用户关系表是否存在，存在则删除项目-人员关系表
        final String unsharesaMark = "unsharesa";
        // 批量取消共享：通过数据ID查询项目明细表是否存在，得到项目ID，然后查询项目用户关系表是否存在，存在则删除项目-人员关系表
        final String unshareBatchMark = "unshareBatch";
        String method = joinPoint.getSignature().getName();
        if(saveMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,保存方法");
            return doSaveMethod(joinPoint);
        }else if(deleteMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,删除方法");
            return doDeleteMethod(joinPoint);
        }else if(assignMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,分派方法");
            return doAssignMethod(joinPoint);
        }else if(shareMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,共享方法");
            return doShareMethod(joinPoint);
        }else if(unsharesaMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,取消分派方法");
            return doUnShareMarkMethod(joinPoint);
        }else if(unshareBatchMark.equalsIgnoreCase(method)){
            log.info("数据操作前处理---->RecordSaveAspect,取消共享方法");
            return doUnShareMarkMethod(joinPoint);
        }else{
            log.info("{}不在拦截范围内", method);
            return joinPoint.proceed();
        }
    }

    @Nullable
    private Object doSaveMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        try{
            JSONObject ret = (JSONObject) result;
            // recordId - 需要处理的实体的ID
            String recordId = ret.getString("id");
            handleEntity(recordId);
        }catch(Exception e){
            log.info("解析异常：{}", result);
            e.printStackTrace();
        }finally {
            return result;
        }
    }

    @Nullable
    private Object doDeleteMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        try{
            // 租户编码
            String tenantCode = UserContextHolder.getTenant();
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            ID[] records = parseIdList(request);
            if(Objects.nonNull(records) && records.length > 0){
                List<String> recordIds = Arrays.stream(records).map(record -> record.toString()).collect(Collectors.toList());
                projectService.deleteProjectDetail(recordIds, tenantCode);
                log.info("查询的记录：{}", records);
            }else{
                log.info("查询的记录不存在：{}", records);
            }
        }catch(Exception e){
            log.info("解析异常：{}", result);
            e.printStackTrace();
        }finally {
            return result;
        }
    }

    @Nullable
    private Object doAssignMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        try{
            // 租户编码
            String tenantCode = UserContextHolder.getTenant();
            JSONObject ret = (JSONObject) result;
            log.info("分派操作数据：{}",ret);
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            ID[] records = parseIdList(request);
            ID[] tos = parseToList(request);// 分派给to
            if(Objects.nonNull(records) && records.length > 0){
                List<String> recordIds = Arrays.stream(records).map(record -> record.toString()).collect(Collectors.toList());
                List<String> toList = Arrays.stream(tos).map(record -> record.toString()).collect(Collectors.toList());
                for (String entityId:recordIds) {
                    // 查询每条记录对应的项目ID
                    TProjectDetailDTO projectDetail = projectService.selectByEntityId(entityId, tenantCode);
                    if (Objects.nonNull(projectDetail)) {
                        ProjectUserPO userPO = new ProjectUserPO();
                        userPO.setProjectCode(projectDetail.getProjectId());
                        userPO.setMembers(toList);
                        userPO.setEntityId(entityId);
                        userPO.setConfigType("ASSIGN");
                        userPO.setTenantCode(tenantCode);
                        projectService.addProjectUser(userPO);
                    }
                }
                log.info("查询的记录：{}", records);
            }else{
                log.info("查询的记录不存在：{}", records);
            }
        }catch(Exception e){
            log.info("解析异常：{}", result);
            e.printStackTrace();
        }finally {
            return result;
        }
    }

    @Nullable
    private Object doShareMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        try{
            // 租户编码
            String tenantCode = UserContextHolder.getTenant();
            JSONObject ret = (JSONObject) result;
            log.info("共享操作数据：{}",ret);
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            ID[] records = parseIdList(request);
            ID[] tos = parseToList(request);// 共享给to
            if(Objects.nonNull(records) && records.length > 0){
                List<String> recordIds = Arrays.stream(records).map(record -> record.toString()).collect(Collectors.toList());
                List<String> toList = Arrays.stream(tos).map(record -> record.toString()).collect(Collectors.toList());
                for (String entityId:recordIds) {
                    // 查询每条记录对应的项目ID
                    TProjectDetailDTO projectDetail = projectService.selectByEntityId(entityId, tenantCode);
                    if (Objects.nonNull(projectDetail)) {
                        ProjectUserPO userPO = new ProjectUserPO();
                        userPO.setProjectCode(projectDetail.getProjectId());
                        userPO.setMembers(toList);
                        userPO.setEntityId(entityId);
                        userPO.setConfigType("SHARE");
                        userPO.setTenantCode(tenantCode);
                        projectService.addProjectUser(userPO);
                    }
                }
                log.info("查询的记录：{}", records);
            }else{
                log.info("查询的记录不存在：{}", records);
            }
        }catch(Exception e){
            log.info("解析异常：{}", result);
            e.printStackTrace();
        }finally {
            return result;
        }
    }

    @Nullable
    private Object doUnShareMarkMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        try{
            // 租户编码
            String tenantCode = UserContextHolder.getTenant();
            JSONObject ret = (JSONObject) result;
            log.info("取消共享操作数据：{}",ret);
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            ID[] records = parseIdList(request);
            String to = getParameterNotNull(request, "to");
            ID[] tos = parseToList(request);// 取消共享给to
            if(Objects.nonNull(records) && records.length > 0){
                List<String> recordIds = Arrays.stream(records).map(record -> record.toString()).collect(Collectors.toList());
                List<String> toList = Arrays.stream(tos).map(record -> record.toString()).collect(Collectors.toList());
                for (String entityId:recordIds) {
                    // 查询每条记录对应的项目ID
                    TProjectDetailDTO projectDetail = projectService.selectByEntityId(entityId, tenantCode);
                    if (Objects.nonNull(projectDetail)) {
                        ProjectUserPO userPO = new ProjectUserPO();
                        userPO.setProjectCode(projectDetail.getProjectId());
                        userPO.setTenantCode(tenantCode);
                        // 全部
                        if ("$ALL$".equals(to)) {
                            userPO.setAllFlag(true);
                        }else {
                            userPO.setAllFlag(false);
                            userPO.setMembers(toList);
                        }
                        projectService.delProjectUser(userPO);
                    }
                }
                log.info("查询的记录：{}", records);
            }else{
                log.info("查询的记录不存在：{}", records);
            }
        }catch(Exception e){
            log.info("解析异常：{}", result);
            e.printStackTrace();
        }finally {
            return result;
        }
    }

    /**
     * 处理实体
     * @param recordId 实体ID
     */
    private void handleEntity(String recordId){
        // 过滤出 实体编码
        Integer entityCode = Integer.parseInt(recordId.substring(0, 3));
        // 租户编码
        String tenantCode = UserContextHolder.getTenant();
        // 根据实体ID 查询要处理的实体
        Record record = getRecordByAdmin(entityCode, recordId);
        if(Objects.isNull(record)){
            return;
        }
        doRecord(tenantCode, record);
        sendMsg(record);
        log.info("查询的记录：{}", record);
    }

    /**
     * admin查询record记录
     * @param entityCode
     * @param recordId
     * @return
     */
    private Record getRecordByAdmin(Integer entityCode, String recordId){
        log.info("通过数据ID查询Record数据：{}", recordId.toString());
        // 商机类型条件：目前仅商机使用，查询指定layout布局
        String conditions = null;
        // 实体
        Entity mEntity = MetadataHelper.getEntity(entityCode);
        // 租户编码
        String tenantCode = UserContextHolder.getTenant();
        // 超级管理员ID
        ID user = UserService.ADMIN_USER;
        // 商机
        if (mEntity.getName().equalsIgnoreCase("rbshangji4")){
            // 如果是商机，根据ID查询商机类型的值
            Object[] object = Application.createQueryNoFilter(
                    "select shangjileixing from rbshangji4 where rbshangji4Id = ? and tenantCode = ?")
                    .setParameter(1, ID.valueOf(recordId))
                    .setParameter(2, tenantCode)
                    .unique();
            conditions = String.valueOf(object[0]);
        }
        // 实体配置
        ConfigBean model = FormsManager.instance.getFormLayout(mEntity.getName(), user, tenantCode, conditions);
        // 实体配置元素
        JSONArray elements = (JSONArray) model.getJSON("elements");
        // 查询到的记录
        Record data = FormsBuilder.instance.findRecord(ID.valueOf(recordId), user, elements, tenantCode);
        return data;
    }

    /**
     * 根据实体定义的字段向上追溯商机，能找到则保存到Project_detail表，不能则说明没有关联商机则意味着没有商机，则不保存
     * @param tenantCode
     * @param record
     */
    public void doRecord(String tenantCode, Record record){
        // 当前实体的类型
        Integer entityCode = record.getEntity().getEntityCode();
        // 判断当前实体是否是需要归集到项目中
        ProjectNeedRecord type = ProjectNeedRecord.getByCode(entityCode);
        if(Objects.isNull(type)){
            log.info("==当前要处理的实体编码是：{}[{}], 不需要记录到项目中", entityCode, record.getEntity().getDescription());
            return;
        }
        ID recordId = record.getPrimary();
        log.info("处理:{}数据：{}", type.msg, recordId.toString());
        // 查询是否存在项目明细
        TProjectDetailDTO detailDTO = projectService.selectByEntityId(recordId.toString(), tenantCode);
        switch (type){
            case rbshangji4:
                doNiche(record, tenantCode, detailDTO);
                break;
            case shouqianxietong28:
                // 售前协同
                doPreSaleCoordination(record, tenantCode, detailDTO, type.resourceID);
                break;
            case toubiaoxietong:
                // 投标协同
                doTenderTogether(record, tenantCode, detailDTO, type.resourceID);
                break;
            case baojiaxietong:
                // 报价协同
                doQuotationTogether(record, tenantCode, detailDTO, type.resourceID);
                break;
            case shouqianfangan:
                // 售前方案
                doPrdSalesPlan(record, tenantCode, detailDTO, type.resourceID);
                break;
            case Quotation:
                // 报价单
                doQuotation(record, tenantCode, detailDTO, type.resourceID);
                break;
            case kuangjiaxieyi:
                // 框架协议（销售）
                doSaleFrameworkAgreement(record, tenantCode, detailDTO, type.resourceID);
                break;
            case rbhetong0:
                // 项目合同（销售）
                doSaleContract(record, tenantCode, detailDTO, type.resourceID);
                break;
            case buchongxieyixiaoshou:
                // 补充协议【销售】
                doBuchongxieyi(record, tenantCode, detailDTO, type.resourceID);
                break;
            case kuangjiaxieyi85:
                // 框架协议（采购）
                doPurFrameworkAgreement(record, tenantCode, detailDTO, type.resourceID);
                break;
            case xiangmuhetong:
                // 项目合同（采购）
                doPurchaseContract(record, tenantCode, detailDTO, type.resourceID);
                break;
            case buchongxieyicaigou:
                // 补充协议【采购】
                doPurchaseBuchongxieyi(record, tenantCode, detailDTO, type.resourceID);
                break;
            case huikuanjihua:
                // 回款计划
                doCollectionPlan(record, tenantCode, detailDTO, type.resourceID);
                break;
            case shoukuanliushui:
                // 收款流水
                doCollectingWater(record, tenantCode, detailDTO, type.resourceID);
                break;
            case fukuanjihua:
                // 付款计划
                doPaymentPlan(record, tenantCode, detailDTO, type.resourceID);
                break;
            case rbfenyong3:
                // 分佣任务
                doCommissionTask(record, tenantCode, detailDTO, type.resourceID);
                break;
            case xiangmujilineibu:
                // 项目激励
                doProjectIncentive(record, tenantCode, detailDTO, type.resourceID);
                break;
            case caigoushijianguanli:
                // 采购事件
                doPurchaseEvent(record, tenantCode, detailDTO, type.resourceID);
                break;
            case jiaofushijianguanli:
                // 交付事件
                doDeliveryEvent(record, tenantCode, detailDTO, type.resourceID);
                break;
            case teshujiageshenpi:
                // 特殊价格申请
                doSpecialPrice(record, tenantCode, detailDTO, type.resourceID);
                break;
            case rbyujiaofu5:
                // 预交付申请
                doAdvanceDelivery(record, tenantCode, detailDTO, type.resourceID);
                break;
            case yongzhangshenpi:
                // 用章申请
                doUseChapter(record, tenantCode, detailDTO, type.resourceID);
                break;
            case hetongshenpi:
                // 销售合同申请
                doSaleContractApproval(record, tenantCode, detailDTO, type.resourceID);
                break;
            case caigouguanli:
                // 采购合同申请
                doPurContractApproval(record, tenantCode, detailDTO, type.resourceID);
                break;
            case fenbaoshenpi:
                // 交付分包申请
                doSubContracting(record, tenantCode, detailDTO, type.resourceID);
                break;
            case xiangmuleibaoxiaoshenpi:
                // 项目类报销申请
                doProjectApply(record, tenantCode, detailDTO, type.resourceID);
                break;
            case xiangmuleifukuan:
                // 项目类付款申请
                doProjectPayment(record, tenantCode, detailDTO, type.resourceID);
                break;
            case rbkaipiao0:
                // 开票申请
                doMakeInvoice(record, tenantCode, detailDTO, type.resourceID);
                break;
            default:
                break;
        }
    }

    /**
     * 新增判断保存实体为审批列表中的实体，则生成提醒提交的一条消息
     * @param record
     */
    private void sendMsg(Record record){
        List<Integer> entityCodes = Arrays.asList(923,937,925,936,884,924,926,928,982);
        // 当前实体的类型
        Integer entityCode = record.getEntity().getEntityCode();
        // 判断当前实体是否是需要归集到项目中
        ProjectNeedRecord type = ProjectNeedRecord.getByCode(entityCode);
        if(Objects.isNull(type)){
            log.info("==当前要处理的实体编码是：{}[{}], 不需要记录到项目中", entityCode, record.getEntity().getDescription());
            return;
        }
        StringBuffer contents = new StringBuffer();
        contents.append("有一条 ").append(type.msg).append(" 请及时提交");

        if(entityCodes.contains(entityCode)){
            log.info("数据：{}发送审批消息：{}", record.getPrimary().toString(), contents.toString());
            Application.getNotifications().send(
                    MessageBuilder.createMessage(record.getID("createdBy"), contents.toString(), Message.TYPE_APPROVAL, record.getPrimary()));
        }
    }

    /**
     * 回款计划
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doCollectionPlan(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 销售合同id
            if (data.getID(resourceID) != null){
                String resourceId = data.getID(resourceID).toString();
                // 查询销售合同
                QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("RBHETONG0_ID", resourceId);
                List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
                if(CollectionUtils.isEmpty(saleContracts)){
                    log.info("销售合同{}不存在", recordId);
                    return;
                }
                // 销售合同关联的商机ID
                String saleContractId = saleContracts.get(0).getShangjibianhao();
                if (StringUtils.isBlank(saleContractId)){
                    log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                    return;
                }
                TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
                if (Objects.nonNull(projectDetail)) {
                    addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
                } else {
                    log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                }
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 付款计划
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPaymentPlan(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        // 项目合同（采购）-销售后合同-商机
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 收款流水id查询回款单
            String resourceId = data.getID(resourceID).toString();
            String nicheId= tRbhetong0Mapper.selectByPurchaseContractId(resourceId);
            if (StringUtils.isBlank(nicheId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(nicheId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 收款流水
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doCollectingWater(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        // 收款流水-回款单-回款计划-销售合同-商机
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 收款流水id查询销售合同的商机ID
            String resourceId = data.getID(resourceID).toString();
            String nicheId= tRbhetong0Mapper.selectByCollectingWaterId(resourceId);
            if (StringUtils.isBlank(nicheId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(nicheId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 补充协议(采购)
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPurchaseBuchongxieyi(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 原采购合同id
            String resourceId = data.getID(resourceID).toString();
            String nicheId= tRbhetong0Mapper.selectByPurchaseContractId(resourceId);
            if (StringUtils.isBlank(nicheId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(nicheId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理采购合同
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPurchaseContract(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 采购合同审批id
            String resourceId = data.getID(resourceID).toString();

            // 查询采购合同审批
            QueryWrapper<TCaigouguanliDTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("CAIGOUGUANLI_ID", resourceId);
            List<TCaigouguanliDTO> caigouguanliDTOS = caigouguanliMapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(caigouguanliDTOS)){
                log.info("采购合同申请{}不存在", recordId);
                return;
            }
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("RBHETONG0_ID", caigouguanliDTOS.get(0).getGuanlianxiaoshouhetong());
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper1);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理商机
     * @param data
     */
    private void doNiche(Record data, String tenantCode, TProjectDetailDTO detailDTO){
        ID recordId = data.getPrimary();
        if (data.getID("shangjileixing") != null){
            String nicheType= data.getID("shangjileixing").toString();
            if("019-01813cebc87b0174".equalsIgnoreCase(nicheType)){
                log.info("商机：{}类型为超能宝商机，不生成项目", recordId);
                // 但是新增和修改都需要同步超能宝商机rbshangji1
                syncRbShangJi1(data);
                return;
            }
        }
        // 当商机阶段是初步接洽时，不生成项目
        String noCreateProjectMark = "019-017a613964f9000d";
        String winRate= data.getID("shangjijieduanyinglv").toString();
        if(noCreateProjectMark.equalsIgnoreCase(winRate)){
            log.info("商机：{}当前是初步接洽阶段，不生成项目", recordId);
            return;
        }
        // 项目阶段 0 销售阶段 1 签约阶段 2 履约阶段 3 已终止 4 已完成
        Integer projectPhase = 0;
        switch (winRate) {
            // 赢率 0.30（需求确认）->销售阶段
            case "019-017a61392960000c":
                projectPhase = 0;
                break;
            // 赢率 0.60（方案谈判）
            case "019-017a6138b982000b":
                projectPhase = 0;
                break;
            // 赢率 0.80（待签约）
            case "019-017a613859b2000a ":
                projectPhase = 0;
                break;
            // 赢率 0.90（签约中）
            case "019-017a6137dfff0009":
                projectPhase = 0;
                break;
            // 赢率 1.00（赢单）
            case "019-017a613777930008":
                projectPhase = 1;
                break;
            // 输单（输单）
            case "019-017a61371dfc0007":
                projectPhase = 3;
                break;
            default:
                break;
        }

        // 如果不存在新增项目
        if(Objects.isNull(detailDTO)){
            log.info("----------------> 商机{}在租户{}下不存在，需要新增", recordId.toString(), tenantCode);
            String accessAddress = h5Url + data.getEntity().getName() + "&id=" + recordId.toString();
            ProjectAddPO addPO = new ProjectAddPO();
            addPO.setTenantCode(tenantCode);
            addPO.setAccessAddress(accessAddress);
            addPO.setEntityCode(data.getEntity().getName());
            addPO.setEntityId(recordId.toString());
            addPO.setNodeCode(data.getEntity().getName());
            addPO.setNodeName(data.getEntity().getDescription());
            addPO.setProjectDesc(data.getString("shangjimiaoshu"));
            // 修改默认项目名称为商机名称
            addPO.setProjectName(data.getString("rbshangji4Name"));
            ID owningUser = data.getID("owningUser");
            addPO.setProjectManager(UserHelper.getName(owningUser));
            addPO.setProjectNo(data.getString("shangjibianhao"));
            addPO.setNicheId(data.getID("rbshangji4Id").toString());
            addPO.setProjectPhase(projectPhase);
            addPO.setCreatedBy(data.getID("createdBy").toString());
            projectService.initProject(addPO);
        }else{
            // 如果存在更新项目
            log.info("----------------> 商机{}在租户{}下已经存在了，需要更新", recordId.toString(), tenantCode);
            // 产品LB已确认：目前没有审批流所以阶段不存在终态，即中止或者完成也能修改阶段，会根据不同的操作修改阶段
           /* // 项目已终止/完成状态下 不可编辑项目信息
            TProjectDTO dto = projectService.selectProjectByProjectId(detailDTO.getProjectId(), detailDTO.getTenantCode());
            if (Objects.nonNull(dto)) {
                if (dto.getProjectPhase() == 3 || dto.getProjectPhase() == 4){
                    log.info("----------------> 项目已终止/完成，不做项目信息的编辑");
                    return;
                }
            }*/
            // 如果商机ID未被销售合同引用，即没有生成销售合同 则可修改项目阶段
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("SHANGJIBIANHAO", data.getID("rbshangji4Id").toString());
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                ProjectUpdatePO updatePO = new ProjectUpdatePO();
                updatePO.setProjectId(detailDTO.getProjectId());
                updatePO.setProjectPhase(projectPhase);
                updatePO.setTenantCode(tenantCode);
                projectService.projectUpdate(updatePO);
            }
        }
    }

    /**
     * 商机类型为超能宝商机，新增，修改后同步到超能宝商机rbshangji1
     */

    private void syncRbShangJi1(Record data){
        log.info("开始：商机类型为超能宝商机，新增，修改后同步到超能宝商机rbshangji1:{}", data.getString("shangjibianhao"));
        TRbshangji1DTO dto = new TRbshangji1DTO();
        QueryWrapper<TRbshangji1DTO> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("SHANGJIBIANHAO", data.getString("shangjibianhao"));
        List<TRbshangji1DTO> list = rbshangji1Mapper.selectList(queryWrapper);
        // 商机id
        ID id= ID.newId(EntityHelper.RbShangJi1);
        dto.setRbshangji1Id(String.valueOf(id));
        dto.setRbshangji1Name(data.getString("rbshangji4Name"));
        dto.setCreatedBy(String.valueOf(data.getID("createdBy")));
        dto.setCreatedOn(data.getDate("createdOn"));
        dto.setModifiedBy(String.valueOf(data.getID("modifiedBy")));
        dto.setModifiedOn(data.getDate("modifiedOn"));
        dto.setTenantCode(data.getString("tenantCode"));
        dto.setOwningUser(String.valueOf(data.getID("owningUser")));
        dto.setOwningDept(String.valueOf(data.getID("owningDept")));
        dto.setShangjibianhao(data.getString("shangjibianhao"));
        dto.setShangjijieduanyinglv(String.valueOf(data.getID("shangjijieduanyinglv")));
        dto.setShangjijineweishui(data.getDecimal("shangjijineyuan"));
        dto.setShangjijinehanshui(data.getDecimal("shangjijinehanshui"));
        dto.setShuilv(BigDecimal.valueOf(data.getLong("shuilv")));
        dto.setYujiqianyueriqi(data.getDate("yujijieshushijian"));
        dto.setGuanliankehu(data.getID("guanliankehu97") == null?null:String.valueOf(data.getID("guanliankehu97")));
        dto.setKehumingcheng(data.getString("kehumingcheng"));
        dto.setGuanlianzuizhongkehu(data.getID("guanlianzuizhongkehu") == null?null:String.valueOf(data.getID("guanlianzuizhongkehu")));
        dto.setZuizhongkehumingcheng(data.getString("zuizhongkehumingcheng"));
        dto.setYuanshixiansuomingcheng(data.getString("yuanshixiansuomingcheng"));
        dto.setGuanlianxiansuo(data.getID("xiansuoyinyong") == null?null:String.valueOf(data.getID("xiansuoyinyong")));
        dto.setXiaowangyuanyin(data.getID("xiaowangyuanyin") == null?null:String.valueOf(data.getID("xiaowangyuanyin")));
        dto.setRbshengshiqu8(data.getID("suozaidiqu") == null?null:String.valueOf(data.getID("suozaidiqu")));
        dto.setXiangxidizhi(data.getString("lianxirendizhi"));
        dto.setLaiyuanqudao(data.getID("laiyuanqudao") == null?null:String.valueOf(data.getID("laiyuanqudao")));
        dto.setDingdanbianhao(data.getString("dingdanbianhao"));
        dto.setRbbeizhu7(data.getString("rbbeizhu7"));
        dto.setRblianxiren5(data.getString("rblianxiren5"));
        dto.setLianxidianhua(data.getString("lianxidianhua"));
        dto.setRblianxiren0(data.getString("rblianxiren0"));
        dto.setLianxidianhua49(data.getString("lianxidianhua49"));
        dto.setShangjiyingdanshijian(data.getDate("shangjiyingdanshijian"));
        dto.setShoujianshebeiqingdanfujian(data.getString("shoujianshebeiqingdanfujian"));
        dto.setToubaobaodan(data.getString("toubaobaodan"));
        if (CollectionUtils.isEmpty(list)){
            rbshangji1Mapper.insert(dto);
        }else {
            rbshangji1Mapper.update(dto, queryWrapper);
        }
        log.info("结束：商机类型为超能宝商机，新增，修改后同步到超能宝商机rbshangji1:{}", data.getString("shangjibianhao"));
    }
    /**
     * 处理合同
     * @param data
     */
    private void doSaleContract(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }


    private void doRecord(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID) {
        // 项目已终止/完成状态下 不可编辑项目信息
        /*TProjectDTO dto = projectService.selectProjectByProjectId(detailDTO.getProjectId(), detailDTO.getTenantCode());
        if (Objects.nonNull(dto)) {
            if (dto.getProjectPhase() == 3 || dto.getProjectPhase() == 4){
                log.info("----------------> 项目已终止/完成，不做项目信息的编辑");
                return;
            }
        }*/
        ID recordId = data.getPrimary();
        if (Objects.nonNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下已存在，需要删除历史", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            projectService.deleteProjectDetail(Arrays.asList(recordId.toString()), tenantCode);
        }
        String projectId = null;
        // 前置节点ID
        String resourceId = data.getID(resourceID).toString();
        TProjectDetailDTO resource = projectService.selectByEntityId(resourceId, tenantCode);
        if (Objects.nonNull(resource)) {
            addProjectDetail(data, tenantCode, recordId, resource.getProjectId());
            projectId = resource.getProjectId();
        } else {
            log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
        }


        // 销售合同已生效 -> 项目阶段为2 履约阶段
        ProjectNeedRecord type = ProjectNeedRecord.getByCode(data.getEntity().getEntityCode());
        if(ProjectNeedRecord.rbhetong0.equals(type)){

            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("RBHETONG0_ID", recordId.toString());
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // LB确认是否满足“合同金额（含税）=已回款金额+罚款金额”
            BigDecimal qianyuejine = saleContracts.get(0).getQianyuejine()==null?BigDecimal.ZERO:saleContracts.get(0).getQianyuejine();
            BigDecimal yihuikuanjine = saleContracts.get(0).getYihuikuanjine()==null?BigDecimal.ZERO:saleContracts.get(0).getYihuikuanjine();
            BigDecimal fakuanjine = saleContracts.get(0).getFakuanjine()==null?BigDecimal.ZERO:saleContracts.get(0).getFakuanjine();

            // 合同阶段 = 已生效
            String finished = "019-0179930eb22201fc";
            String canceled = "019-0179930e6def01fa";
            String hetongjieduan = data.getID("hetongjieduan").toString();
            ProjectUpdatePO updatePO = new ProjectUpdatePO();
            updatePO.setProjectId(projectId);
            updatePO.setTenantCode(tenantCode);
            if (canceled.equalsIgnoreCase(hetongjieduan)){
                log.info("合同现阶段{}需要更新项目的状态为{} 已中止", hetongjieduan, "3 已中止");
                updatePO.setProjectPhase(3);
            }else {
                if(qianyuejine.compareTo(yihuikuanjine.add(fakuanjine))==0){
                    log.info("合同现阶段{}需要更新项目的状态为{} 已完成", hetongjieduan, "4 已完成");
                    updatePO.setProjectPhase(4);
                }else if(finished.equalsIgnoreCase(hetongjieduan)){
                    log.info("合同现阶段{}需要更新项目的状态为{} 履约阶段", hetongjieduan, "2 履约阶段");
                    updatePO.setProjectPhase(2);
                }else{
                    log.info("合同现阶段{}需要更新项目的状态为{} 签约阶段", hetongjieduan, "1 签约阶段");
                    updatePO.setProjectPhase(1);
                }
            }
            projectService.projectUpdate(updatePO);

        }else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 售前协同
     * @param data
     * @param tenantCode
     */
    private void doPreSaleCoordination(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 投标协同
     * @param data
     * @param tenantCode
     */
    private void doTenderTogether(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 报价协同
     * @param data
     * @param tenantCode
     */
    private void doQuotationTogether(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 售前方案
     * @param data
     * @param tenantCode
     */
    private void doPrdSalesPlan(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 报价单
     * @param data
     * @param tenantCode
     */
    private void doQuotation(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 框架协议(销售)
     * @param data
     * @param tenantCode
     */
    private void doSaleFrameworkAgreement(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理补充协议（销售）
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doBuchongxieyi(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理分佣任务
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doCommissionTask(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理项目激励
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doProjectIncentive(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理特殊价格审批
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doSpecialPrice(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理预交付申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doAdvanceDelivery(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理用章申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doUseChapter(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理销售合同申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doSaleContractApproval(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理采购合同申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPurContractApproval(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 销售合同id
            String resourceId = data.getID(resourceID).toString();
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("RBHETONG0_ID", resourceId);
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理交付分包申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doSubContracting(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 销售合同id
            String resourceId = data.getID(resourceID).toString();
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("RBHETONG0_ID", resourceId);
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理项目类报销申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doProjectApply(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理项目类付款申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doProjectPayment(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        doRecord(data, tenantCode, detailDTO, resourceID);
    }

    /**
     * 处理开票申请
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doMakeInvoice(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        // 收款流水-回款单-回款计划-销售合同-商机
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 收款流水id查询销售合同的商机ID
            String resourceId = data.getID(resourceID).toString();
            String nicheId= tRbhetong0Mapper.selectByCollectionPlanId(resourceId);
            if (StringUtils.isBlank(nicheId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(nicheId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }


    /**
     * 处理采购事件
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPurchaseEvent(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 销售合同id
            String resourceId = data.getID(resourceID).toString();
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("RBHETONG0_ID", resourceId);
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理交付事件
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doDeliveryEvent(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 销售合同id
            String resourceId = data.getID(resourceID).toString();
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("RBHETONG0_ID", resourceId);
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }

    /**
     * 处理补充协议（采购）
     * @param data
     * @param tenantCode
     * @param detailDTO
     * @param resourceID
     */
    private void doPurFrameworkAgreement(Record data, String tenantCode, TProjectDetailDTO detailDTO, String resourceID){
        ID recordId = data.getPrimary();
        if (Objects.isNull(detailDTO)) {
            log.info("----------------> {}{}在租户{}下不存在，需要新增", data.getEntity().getDescription(), recordId.toString(), tenantCode);
            // 采购合同审批id
            String resourceId = data.getID(resourceID).toString();

            // 查询采购合同审批
            QueryWrapper<TCaigouguanliDTO> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("CAIGOUGUANLI_ID", resourceId);
            List<TCaigouguanliDTO> caigouguanliDTOS = caigouguanliMapper.selectList(queryWrapper);
            if(CollectionUtils.isEmpty(caigouguanliDTOS)){
                log.info("采购合同申请{}不存在", recordId);
                return;
            }
            // 查询销售合同
            QueryWrapper<TRbhetong0DTO> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("RBHETONG0_ID", caigouguanliDTOS.get(0).getGuanlianxiaoshouhetong());
            List<TRbhetong0DTO> saleContracts = tRbhetong0Mapper.selectList(queryWrapper1);
            if(CollectionUtils.isEmpty(saleContracts)){
                log.info("销售合同{}不存在", recordId);
                return;
            }
            // 销售合同关联的商机ID
            String saleContractId = saleContracts.get(0).getShangjibianhao();
            if (StringUtils.isBlank(saleContractId)){
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
                return;
            }
            TProjectDetailDTO projectDetail = projectService.selectByEntityId(saleContractId, tenantCode);
            if (Objects.nonNull(projectDetail)) {
                addProjectDetail(data, tenantCode, recordId, projectDetail.getProjectId());
            } else {
                log.info("{}的前置节点【{}}:{}】不存在", data.getEntity().getDescription(), resourceId);
            }
        } else {
            log.info("{}已经存在", data.getEntity().getDescription());
        }
    }


    /**
     * 新增项目明细
     * @param data
     * @param tenantCode
     * @param recordId
     * @param projectId
     */
    private void addProjectDetail(Record data, String tenantCode, ID recordId, String projectId) {
        String accessAddress = h5Url + data.getEntity().getName() + "&id=" + recordId.toString();
        ProjectAndDetailUpdatePO addPO = new ProjectAndDetailUpdatePO();
        addPO.setTenantCode(tenantCode);
        addPO.setAccessAddress(accessAddress);
        addPO.setEntityCode(data.getEntity().getName());
        addPO.setEntityId(recordId.toString());
        addPO.setNodeCode(data.getEntity().getName());
        addPO.setNodeName(data.getEntity().getDescription());
        projectService.addProjectDetail(addPO, projectId);
    }

    /**
     * 需要记录到项目中的类型
     */
    enum ProjectNeedRecord{
        rbshangji4(991, "商机", ""),
        // 方案
        shouqianxietong28(909, "售前协同", "guanlianshangji"),
        toubiaoxietong(934, "投标协同", "rbshangji1"),
        baojiaxietong(871, "报价协同", "guanlianshangji"),
        shouqianfangan(920, "售前方案", "guanlianshangji"),
        Quotation(993, "报价单", "guanlianshangji"),

        // 合约
        kuangjiaxieyi(915, "框架协议（销售）", "guanlianshangji"),
        rbhetong0(992, "项目合同（销售）", "shangjibianhao"),
        buchongxieyixiaoshou(908, "补充协议【销售】", "guanlianyuanhetong52"),
        kuangjiaxieyi85(914, "框架协议（采购）", "shenpijilu"),
        xiangmuhetong(913, "项目合同（采购）", "shenpijilu"),
        buchongxieyicaigou(907, "补充协议【采购】", "guanlianyuancaigouhetong"),

        // 财务管理
        huikuanjihua(986, "回款计划", "guanlianhetong"), // 销售合同
        shoukuanliushui(918, "收款流水", "shoukuanliushuiId"), // 收款流水-回款单-回款计划-销售合同-商机
        fukuanjihua(906, "付款计划", "guanlianhetong"), // 项目合同（采购）-销售后合同-商机
        rbfenyong3(981, "分佣任务", "guanlianshangji"),
        xiangmujilineibu(896, "项目激励", "guanlianshangji"),
        jiaofushijianguanli(875, "交付事件管理", "guanlianxiangmuhetong"),
        caigoushijianguanli(872, "采购事件管理", "guanlianxiangmuhetong"),
        teshujiageshenpi(923, "特殊价格申请", "guanlianshangji"),
        rbyujiaofu5(937, "预交付申请", "rbshangji7"),
        yongzhangshenpi(925, "用章申请", "guanlianshangji"),
        hetongshenpi(936, "销售合同申请", "guanlianshangjibianhao"),
        caigouguanli(884, "采购合同申请", "guanlianxiaoshouhetong"),
        fenbaoshenpi(924, "交付分包申请", "guanlianhetong"),
        xiangmuleibaoxiaoshenpi(926, "项目类报销申请", "guanlianshangji"),
        xiangmuleifukuan(928, "项目类付款申请", "guanlianshangji"),
        rbkaipiao0(982, "开票申请", "huikuanjihua"),
        /*
        // 本期不涉及的实体
        rbfuwudan2(941, "服务单管理", "guanlianxiaoshouxiangmuhetong"),
        yingjicaigoudingdan(883, "应急采购订单", "hetongbianhao"),
        jihuacaigouxiangmu(886, "维保拆包采购订单", "hetongbianhao"),
        jihuacaigoudingdanshangpin(882, "计划采购订单", "hetongbianhao"),*/;



        private Integer code;
        private String msg;
        private String resourceID;

        ProjectNeedRecord(Integer code, String msg, String resourceID){
            this.code = code;
            this.msg = msg;
            this.resourceID = resourceID;
        }

        /**
         * 根据code查询实例
         * @param entityCode
         * @return
         */
        public static ProjectNeedRecord getByCode(Integer entityCode){
            ProjectNeedRecord[] values = ProjectNeedRecord.values();
            for(ProjectNeedRecord value : values){
                if(value.code.equals(entityCode)){
                    return value;
                }
            }
            return null;
        }
    }

    private ID[] parseIdList(HttpServletRequest request) {
        String ids = getParameterNotNull(request, "id");

        Set<ID> idList = new HashSet<>();
        int sameEntityCode = 0;
        for (String id : ids.split(",")) {
            if (!ID.isId(id)) {
                continue;
            }
            ID id0 = ID.valueOf(id);
            if (sameEntityCode == 0) {
                sameEntityCode = id0.getEntityCode();
            }
            if (sameEntityCode != id0.getEntityCode()) {
                throw new InvalidParameterException(Language.L("BatchOpMustSameEntity"));
            }
            idList.add(ID.valueOf(id));
        }
        return idList.toArray(new ID[0]);
    }

    private ID[] parseToList(HttpServletRequest request) {
        String ids = getParameterNotNull(request, "to");

        Set<ID> idList = new HashSet<>();
        int sameEntityCode = 0;
        for (String id : ids.split(",")) {
            if (!ID.isId(id)) {
                continue;
            }
            ID id0 = ID.valueOf(id);
            if (sameEntityCode == 0) {
                sameEntityCode = id0.getEntityCode();
            }
            if (sameEntityCode != id0.getEntityCode()) {
                throw new InvalidParameterException(Language.L("BatchOpMustSameEntity"));
            }
            idList.add(ID.valueOf(id));
        }
        return idList.toArray(new ID[0]);
    }

    protected String getParameterNotNull(HttpServletRequest request, String name) {
        String v = request.getParameter(name);
        if (StringUtils.isEmpty(v)) {
            throw new InvalidParameterException("参数不存在");
        }
        return v;
    }
}